package com.coderman.youpinshop.stock.service.impl;

import com.coderman.youpinshop.stock.bo.StockChangeEvent;
import com.coderman.youpinshop.stock.cache.StockCacheService;
import com.coderman.youpinshop.stock.dataobject.StockDO;
import com.coderman.youpinshop.stock.dataobject.StockRecordDO;
import com.coderman.youpinshop.stock.enums.StockOperationEnum;
import com.coderman.youpinshop.stock.mapper.StockMapper;
import com.coderman.youpinshop.stock.mapper.StockRecordMapper;
import com.coderman.youpinshop.stock.mq.StockMqSerivce;
import com.coderman.youpinshop.stock.service.StockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * Description:
 * date: 2022/1/15
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
@Component(value = "commonStockService")
public class CommonStockServiceImpl implements StockService {
    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private StockRecordMapper stockRecordMapper;

    @Autowired
    private StockMqSerivce stockMqSerivce;

    @Autowired
    private StockCacheService stockCacheService;


    @Override
    public boolean deduct(String stockCode, Integer deductCount) {
        //这是常规视角下的扣减库存逻辑，同时也是贫血模型的一个标准demo,但是需要说明的是在贫血模型里操作领域模型就是也在操作
        //数据模型，所以这个逻辑里面的todo convert如果实现的话可能只是一个翻版的贫血模型实现，但是好在我们已经把数据库模型
        //从实体模型里分离了出来

        //1. 检查库存记录是否存在
        StockDO stockDO = stockMapper.getByStockCode(stockCode);
        if(stockDO  == null){
            return false;
        }
        //这里可以进行stockDO ---> stockBO操作
        //2. 重新计算库存数量
        if(stockDO.getQuantity() < deductCount){
            return false;
        }
        int oldQuantity = stockDO.getQuantity();
        int newQuantity = stockDO.getQuantity() - deductCount;
        stockDO.setQuantity(newQuantity);

        //3. 构建库存变更记录
        //todo StockRecordBO--> StockRecoredDO
        StockRecordDO stockRecoredDO = new StockRecordDO();
        stockRecoredDO.setStockCode(stockCode);
        stockRecoredDO.setOperationCode(StockOperationEnum.DEDUCT.getCode());
        stockRecoredDO.setBeforeQuantity(oldQuantity);
        stockRecoredDO.setAfterQuantity(newQuantity);
        stockRecoredDO.setOperationDate(new Date());


        //4. 持久化库存 和变更记录
        stockRecordMapper.insert(stockRecoredDO);
        //stockMapper.deduct(stockCode,deductCount);
        stockMapper.updateQuantity(stockCode,newQuantity);

        //5. 更新缓存
        stockCacheService.deduct(stockCode,deductCount);

        //6. 发送mq

        stockMqSerivce.sendStockChangeMq(StockChangeEvent.builder()
                .changeQuantity(deductCount)
                .opearationCode(StockOperationEnum.DEDUCT.getCode()).build());
        return true;

    }
}
